home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C
/
Applications
/
Cheat II
/
original
/
cheatwich.c
< prev
next >
Wrap
Text File
|
1995-01-28
|
18KB
|
725 lines
// Deals with all the shit that happens when the user interrupts
#include "main.h"
#include "cheat.h"
#include "cheatwich.h"
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <Processes.h>
#include <pascal.h>
#include "error.h"
#include <ctype.h>
#define charsizeh 6
#define hchars 40
#define charsizev 12
#define vchars 20
#define hsize (charsizeh * hchars)
#define vsize (charsizev * vchars)
#define wintop 40
#define winleft 20
#define hdrawoffset 2
#define vdrawoffset 2
#define kmincursorh 2
#define kflashtime 60
// externs
long goffset = 0;
long gsearchnum = 0, gnewvalue = 0;
ProcessSerialNumber gplastseen;
// globals
long testlong = 739391133;
Rect windowBounds = {wintop, winleft, wintop + vsize + vdrawoffset * 2, winleft + hsize + hdrawoffset * 2};
Rect saveBounds = {0, 0, vsize + vdrawoffset * 2, hsize + hdrawoffset * 2 + 8};
static char karz[vchars][hchars]; // note v is first!
static char itch[256]; // if you've got an itch, . . .
int cursor, curflash = 0;
static int lastkey, quitflag;
unsigned long lastflash = 0;
ProcessInfoRec dainfo;
ProcessSerialNumber process;
ProcessSerialNumber lastprocess = {0, 0};
Str255 ourtitle, ourcomment;
GWorldPtr savepix;
// allocate memory for offscreen pixmap
void allocmem(void)
{
GDHandle SaveGD;
CGrafPtr SavePort;
OSErr result;
int a;
GetGWorld(&SavePort, &SaveGD);
result = NewGWorld(&savepix, 8, &saveBounds, 0, nil, 0);
if (result) {
stdmessage("\pSorry, not enough memory to start up.");
verify(false);
}
verify(savepix);
a = LockPixels(savepix->portPixMap);
verify(a);
SetGWorld(savepix, nil);
ClipRect(&(*savepix).portRect);
PaintRect(&(*savepix).portRect);
SetGWorld(SavePort, SaveGD);
}
unsigned char kmp[16];
// k = any keyboard scan code, 0-127
static int isPressed(unsigned short k )
{
return ( ( kmp[k>>3] >> (k & 7) ) & 1);
}
static void clearkarz(void)
{
int i, j;
for (i=0;i<hchars;i++) for (j=0;j<vchars;j++) karz[j][i] = ' ';
}
static void drawrow(int v)
{
int i, y = (vchars - v) * charsizev - vdrawoffset;
Rect r;
SetRect(&r, 0, y - charsizev + 3, hsize + 10, y + 3);
EraseRect(&r);
for (i=0;i<hchars;i++) {
MoveTo(i * charsizeh + hdrawoffset, y);
DrawChar(karz[v][i]);
}
}
static void drawcell(int h)
{
int y = (vchars) * charsizev - vdrawoffset;
Rect r;
SetRect(&r, hdrawoffset + cursor * charsizeh, y - charsizev + 3, hdrawoffset + (cursor+1) * charsizeh, y + 3);
EraseRect(&r);
MoveTo(h * charsizeh + hdrawoffset, y);
DrawChar(karz[0][h]);
}
static void newprompt(void)
{
int i;
for (i=0;i<hchars;i++) karz[0][i] = ' ';
karz[0][0] = '>';
drawrow(0);
cursor = kmincursorh;
}
static void scrollit(void)
{
int i, j;
for (j=vchars-1;j>=1;j--)
for (i=0;i<hchars;i++)
karz[j][i] = karz[j-1][i];
for (i=0;i<hchars;i++) karz[0][i] = ' ';
for (j=0;j<vchars;j++)
drawrow(j);
cursor = 0;
}
static void cprintf(char *fmt, ...)
{
va_list args;
int len, cur = 0, ph;
va_start(args, fmt);
len = vsprintf(itch, fmt, args);
do {
ph = cursor;
for (;(cur < len);cur++)
if (ph >= hchars) {
scrollit();
ph = 0;
break;
}
else if (itch[cur] == '\n') {
scrollit();
cur++;
ph = 0;
break;
}
else
karz[0][ph++] = itch[cur];
} while (cur < len);
cursor = ph;
drawrow(0);
va_end(args);
}
static void printprocess(void)
{
char nm[32];
OSErr err;
Boolean res;
if (GetFrontProcess(&process) != noErr)
return;
// clear things up if this isn't the same process
err = SameProcess(&process, &lastprocess, &res);
if (err || !res) {
goffset = 0;
gsearchnum = 0; gnewvalue = 0;
}
BlockMove(&process, &lastprocess, sizeof(ProcessSerialNumber));
dainfo.processInfoLength = sizeof(ProcessInfoRec);
dainfo.processName = (void *) nm;
dainfo.processAppSpec = 0;
if (GetProcessInformation(&process, &dainfo) != noErr)
return;
nm[nm[0]+1] = 0;
cprintf("We've stopped in %s\n", &nm[1]); // output the name
}
static void printstatus(void)
{
cprintf("Search size: %s, ", (gvalsize == ksizelong) ? "long" :
((gvalsize == ksizeint) ? "integer" : "byte"));
cprintf("Search value: %ld, Possibilities: %ld,",
gsearchnum, gcurposs);
cprintf(" Offset: %ld,", goffset);
cprintf(" Change to: %ld\n", gnewvalue);
}
static void flashcursor(int turnoff)
{
Rect r;
int y = vchars * charsizev - vdrawoffset;
SetRect(&r, hdrawoffset + cursor * charsizeh, y - charsizev + 3, hdrawoffset + (cursor+1) * charsizeh, y);
if (TickCount() - lastflash >= kflashtime) {
curflash = !curflash;
lastflash = TickCount();
}
if (turnoff || !curflash)
EraseRect(&r);
else
PaintRect(&r);
}
// the user hit the search button, so let's do it
static void processsearch(void)
{
int *pint, findint, temp;
void *p;
long endsearch, findlong, newposs, *plong, l, startsearch;
Str255 str;
// get the number to search for
findlong = gsearchnum;
findint = findlong;
p = (void *) ((long) dainfo.processLocation + dainfo.processSize);
startsearch = (long) p;
if (!gcurposs) { // starting a new search
// p is start of search, at the largest location in that app's partition
endsearch = (long) dainfo.processLocation;
pint = (int *) p; plong = (long *) p;
switch (gvalsize) {
case ksizelong:
while ((long) plong >= endsearch) {
plong = (long *) ((long) plong - 2); // only decrement two bytes
if (*plong == findlong) { // we've found a possibility
gposs[gcurposs++] = (Ptr) plong; // store it
if (gcurposs>=gmaxposs) // too many values
plong = (void *) (endsearch-4); // this will kill the search
}
}
break;
case ksizeint:
while ((long) pint >= endsearch)
if (*--pint == findint) { // we've found a possibility
gposs[gcurposs++] = (Ptr) pint; // store it
if (gcurposs>=gmaxposs) // too many values
pint = (void *) (endsearch-4); // this will kill the search
}
break;
case ksizebyte:
while ((long) pint >= endsearch) {
pint--;
// first look at high-order byte
temp = (*pint) >> 8;
if (temp == findint) { // we've found a possibility
gposs[gcurposs++] = (Ptr) pint; // store it
if (gcurposs>=gmaxposs) // too many values
pint = (void *) (endsearch-4); // this will kill the search
}
// now look at low-order byte
temp = (*pint) & 0xFF;
if (temp == findint) { // we've found a possibility
gposs[gcurposs++] = (Ptr) ((long) pint + 1); // store it
if (gcurposs>=gmaxposs) // too many values
pint = (void *) (endsearch-4); // this will kill the search
}
}
break;
default: break;
}
}
else { // refining a search
newposs = 0;
switch (gvalsize) {
case ksizelong: // we're dealing in longints
for (l=0;l<gcurposs;l++)
if (*((long *)gposs[l]) == findlong)
gposs[newposs++] = gposs[l];
break;
case ksizeint: // we're dealing in integers
for (l=0;l<gcurposs;l++)
if (*((int *)gposs[l]) == findint)
gposs[newposs++] = gposs[l];
break;
case ksizebyte: // we're dealing in bytes
for (l=0;l<gcurposs;l++)
if ((long) gposs[l] & 1) { // some are odd
// extract low order byte
if ((*((int *)((long) gposs[l] - 1)) & 0xFF) == findint)
gposs[newposs++] = gposs[l];
}
else if ((*((int *)gposs[l]) >> 8) == findint)
gposs[newposs++] = gposs[l];
break;
default: break;
}
gcurposs = newposs;
}
// change the text field of the possibilities item
if (gcurposs)
goffset = startsearch - (long) gposs[0];
else
goffset = 0;
cprintf("Possibilities: %ld\n", gcurposs);
}
// called when a user types change
static void processchange(void)
{
Str255 str;
int changeto, *ip, temp;
short res;
if (goffset == 0) {
cprintf("Error: offset of 0 cannot be valid");
return;
}
if (gcurposs>1)
cprintf("(* warning, value changed without unique location *)\n");
changeto = gnewvalue;
switch (gvalsize) {
case ksizelong: // we're dealing in longints
*((long *) gposs[0]) = gnewvalue; // set the place in memory!
break;
case ksizeint: // we're dealing in integers
if (gnewvalue > 65535) {
cprintf("Error: Change To value is too large for integer.\n");
return;
}
*((int *) gposs[0]) = changeto; // set the place in memory!
break;
case ksizebyte:
if (gnewvalue > 255) {
cprintf("Error: Change To value is too large for byte.\n");
return;
}
if ((long) gposs[0] & 1) { // odd address
ip = (int *) ((long) gposs[0] - 1); // set at word right before byte
// change the low-order byte of this word to what we want
temp = (((*ip) >> 8) << 8) + (changeto & 0xFF);
*ip = temp; // set it in memory
}
else {
ip = (int *) gposs[0]; // treat as word pointer
// change the high-order byte of this word to what we want
temp = (((*ip) << 8) >> 8) + ((changeto & 0xFF) << 8);
*ip = temp; // set it in memory
}
break;
default: cprintf("error!\n"); break;
}
}
// they want to change search value
static void processvalue(char *c, int len)
{
c += len - 1; // put on last char of command
while (*++c == ' '); // skip spaces
if (*c == '\0') {
cprintf("You must supply a value, chump.\n");
return;
}
// finally get the value
gsearchnum = atol(c);
cprintf("Search value: %ld\n", gsearchnum);
}
// they want to change the offset, highly riskeeeeeee
static void processoffset(char *c, int len)
{
c += len - 1; // put on last char of command
while (*++c == ' '); // skip spaces
if (*c == '\0') {
cprintf("You must supply a value, chump.\n");
return;
}
// finally get the value
goffset = atol(c);
cprintf("New offset: %ld\n", goffset);
}
// they want to change the change value
static void processchangevalue(char *c, int len)
{
c += len - 1; // put on last char of command
while (*++c == ' '); // skip spaces
if (*c == '\0') {
cprintf("You must supply a value, wizard.\n");
return;
}
// finally get the value
gnewvalue = atol(c);
cprintf("Change value: %ld\n", gnewvalue);
}
// they want to start over, tabula rasa
static void processstartover(void)
{
gcurposs = 0;
goffset = 0;
}
// they want to save their cheat
static void processsave(void)
{
int i;
if (numwichcuts == kmaxwichcuts) {
cprintf("Error saving: too many cheats have been saved. Return to application\
to save more. (Sorry.)\n");
return;
}
if (!ourtitle[0]) {
cprintf("Error saving: you must supply a title\n");
return;
}
if (goffset>150000)
cprintf("(* warning, value saved is reasonably likely to move about, thus saved position may not work again *)\n");
wichcuts[numwichcuts].offset = goffset;
wichcuts[numwichcuts].datasize = gvalsize;
wichcuts[numwichcuts].newval = gnewvalue;
for (i=0;i<100;i++) {
wichcuts[numwichcuts].title[i] = ourtitle[i];
wichcuts[numwichcuts].comment[i] = ourcomment[i];
}
numwichcuts++; // we just added one
}
// returns true if strings are equal (ignoring case)
static int eqstring(char *c, Str255 s)
{
int i = 1;
while (*c)
if (*c++ != toupper(s[i++]))
return false;
return true;
}
// they want to open a saved shortcut
static void processopen(char *c, int len)
{
int i;
shortcut sc;
if (!len) {
cprintf("Error opening: you must supply a title\n");
return;
}
c += 5;
sc.title[0] = 0;
// find the shortcut with the given title
// first look in shit we just did
for (i=0;i<numwichcuts;i++)
if (eqstring(c, wichcuts[i].title)) {
sc = wichcuts[i];
break;
}
// now look in the main list
HLock((Handle) cut);
if (i == numwichcuts) // only if not already found
for (i=0;i<gnumcuts;i++)
if (eqstring(c, (*cut)[i].title)) {
sc = (*cut)[i];
break;
}
HUnlock((Handle) cut);
if (!sc.title[0]) {
cprintf("Error opening: cheat could not be found\n");
return;
}
cprintf("Cheat opened\n");
goffset = sc.offset;
if (goffset>150000)
cprintf("(* warning, there's a good chance this cheat will not work, and might also crash the program *)\n");
gvalsize = sc.datasize;
gnewvalue = sc.newval;
for (i=0;i<254;i++) {
ourtitle[i] = sc.title[i];
ourcomment[i] = sc.comment[i];
}
gcurposs = 1;
}
// they want to change size of datum for which they are searching
static void processsize(char *c, int len)
{
c += len - 1; // put on last char of command
while (*++c == ' '); // skip spaces
if (*c == '\0') {
cprintf("You must supply a value, bud.\n");
return;
}
// finally get the value, switch the first char of the word
switch (*c) {
case 'B': gvalsize = ksizebyte; break;
case 'I': gvalsize = ksizeint; break;
case 'L': gvalsize = ksizelong; break;
default:
cprintf("Not a valid size.\n");
return;
break;
}
cprintf("Search size: %s\n", (gvalsize == ksizelong) ? "long" :
((gvalsize == ksizeint) ? "integer" : "byte"));
}
// they want to change size of datum for which they are searching
static void processtitle(char *c, int len)
{
char ch;
c += len - 1; // put on last char of command
while (*++c == ' '); // skip spaces
strcpy((char *) ourtitle, c);
cprintf("Title set to %s\n", (char *) ourtitle);
(void) CtoPstr((char *) ourtitle);
}
// they want to change size of datum for which they are searching
static void processcomment(char *c, int len)
{
char ch;
c += len - 1; // put on last char of command
while (*++c == ' '); // skip spaces
strcpy((char *) ourcomment, c);
cprintf("Comment set to %s\n", (char *) ourcomment);
(void) CtoPstr((char *) ourcomment);
}
static void processline(char *c)
#define checkcom(shouldbe) (((long) strstr(c, shouldbe) == (long) c) && (len = strlen(shouldbe)))
{
int len;
if (checkcom("QUIT"))
quitflag = true;
else if (checkcom("STATUS") || checkcom("SS"))
printstatus();
else if (checkcom("SEARCHVALUE") || checkcom("SV"))
processvalue(c, len);
else if (checkcom("OFFSET"))
processoffset(c, len);
else if (checkcom("CHANGEVALUE") || checkcom("CV"))
processchangevalue(c, len);
else if (checkcom("SEARCH") || checkcom("SH")) {
processsearch();
printstatus();
}
else if (checkcom("SIZE"))
processsize(c, len);
else if (checkcom("TITLE"))
processtitle(c, len);
else if (checkcom("COMMENT"))
processcomment(c, len);
else if (checkcom("SAVE"))
processsave();
else if (checkcom("OPEN"))
processopen(c, len);
else if (checkcom("CHANGE") || checkcom("CE"))
processchange();
else if (checkcom("STARTOVER") || checkcom("SO"))
processstartover();
else if (checkcom("HELP")) {
len = strlen(c);
if (len > 4) {
c += 5; // advance past "HELP"
if (checkcom("SIZE"))
cprintf("SIZE x; where x is either LONGINT (L), INTEGER (I), or BYTE (B)\n");
else if (checkcom("SEARCHVALUE"))
cprintf("SEARCHVALUE x; where x is the number to search for\n");
else if (checkcom("CHANGEVALUE"))
cprintf("CHANGEVALUE x; where x is the new number to change to\n");
else if (checkcom("OPEN"))
cprintf("OPEN f; where f is the name of the Cheat, listed in Cheat Sheet window\n");
}
else {
cprintf("the valid comands are:\n");
cprintf("QUIT, STATUS (SS), SIZE, SEARCH (SH), STARTOVER (SO), SEARCHVALUE (SV),\
CHANGEVALUE (CV), CHANGE (CE), OPEN, SAVE, TITLE, COMMENT\n");
cprintf("type 'HELP subject' to get more specific help in following subjects:\n");
cprintf("SIZE, SEARCHVALUE, CHANGEVALUE, OPEN");
}
}
else
cprintf("Not a command. Sorry champ.\n");
}
// the character strings for char code equivs, yuch
#define knumchars 0x38
const char (keychar[knumchars]) = {
'A', 'S', 'D', 'F', 'H', 'G', 'Z', 'X',
'C', 'V', '\0', 'B', 'Q', 'W', 'E', 'R',
'Y', 'T', '1', '2', '3', '4', '6', '5',
'=', '9', '7', '-', '8', '0', ']', 'O',
'U', '[', 'I', 'P', '\x0D', 'L', 'J', '\0',
'K', ';', '\\', ',', '/', 'N', 'M', '.',
'\0', ' ', '\0', '\x01', '\0', '\0', '\0', '\0' // 38
};
static void keycheck(long oldtrap)
{
int i, code, j, oc;
if (!oldtrap) // we're testing or somesuch
GetKeys((long *) kmp);
else
CallPascal((long *) kmp, oldtrap);
code = -1;
for (i=0;i<16;i++)
if (kmp[i]) {
for (j=0;j<=7;j++)
if ((kmp[i]>>j)&1)
if ((i*8 + j) <= 0x70)
code = i * 8 + j;
}
if (code == lastkey)
return; // hasn't lifted up key yet
lastkey = code;
if ((code >= 0) && (code < knumchars) && keychar[code]) {
if (keychar[code] == 0x01) { // delete
if (cursor > kmincursorh) { // can't delete too much
drawcell(cursor);
cursor--;
karz[0][cursor] = ' ';
drawcell(cursor);
curflash = 0;
lastflash = 0;
}
}
else if (keychar[code] == 0x0D) { // return
oc = cursor;
scrollit();
karz[1][oc] = '\0';
processline(&karz[1][2]); // it's been scrolled up
karz[1][oc] = ' ';
newprompt();
}
else if (cursor < hchars-1) {
karz[0][cursor] = keychar[code];
drawcell(cursor);
cursor++;
curflash = 0;
lastflash = 0;
}
}
}
static void mainloop(long oldtrap)
{
int k;
lastkey = -1;
quitflag = 0;
clearkarz();
printprocess();
shouldclearup = true;
printstatus();
cprintf("type 'HELP' for more help\n");
newprompt();
while (!quitflag) {
flashcursor(false);
keycheck(oldtrap);
}
}
int cheatwich(long oldtrap)
{
GDHandle SaveGD;
CGrafPtr SavePort;
WindowPtr wichWindow, frontone;
CGrafPort daport;
GetGWorld(&SavePort, &SaveGD);
/* frontone = FrontWindow();
wichWindow = NewWindow(0L, &windowBounds, "\p", true, altDBoxProc, (WindowPtr) -1L, false, 0);
if (!wichWindow)
return false;
SetPort(wichWindow); */
OpenCPort(&daport);
// save the contents of this part of screen into GWorld
SetGWorld(savepix, nil);
CopyBits ((BitMap *) *(daport.portPixMap), (BitMap *) *(savepix->portPixMap),
&saveBounds, &saveBounds, srcCopy, nil);
SetGWorld(&daport, nil);
TextFont(monaco);
TextSize(9);
mainloop(oldtrap);
// DisposeWindow(wichWindow);
// if (frontone)
// BringToFront(frontone);
CopyBits ((BitMap *) *(savepix->portPixMap), (BitMap *) *(daport.portPixMap),
&saveBounds, &saveBounds, srcCopy, nil);
CloseCPort(&daport);
SetGWorld(SavePort, SaveGD);
FlushEvents(everyEvent, 0);
return true; // all okay
}